#include <iostream>

using std::cout;
using std::endl;

struct Base
{
    virtual void Func() {}
    virtual ~Base() {}
};

struct DerivedB : Base
{
    void Func() override
    {
        cout << "call func in DerivedB" << endl;
    }
};

struct DerivedC : Base
{
    void Func() override
    {
        cout << "call func in DerivedC" << endl;
    }
};

struct DerivedD : Base
{
    void Func() override
    {
        cout << "call func in DerivedD" << endl;
    }
};

class A
{
public:
    A(Base *interfaceB) : m_interfaceB(interfaceB) {}
    void Func()
    {
        m_interfaceB->Func();
    }

    ~A()
    {
        if (m_interfaceB != nullptr)
        {
            delete m_interfaceB;
            m_interfaceB = nullptr;
        }
    }

private:
    Base *m_interfaceB;
};

int main(void)
{
    A *a = new A(new DerivedB());
    a->Func();
    delete a;

    /*
      A *a = nullptr;
    if (conditionB)
        a = new A(new DervedB());
    else if (conditionB)
        a = new A(new DervedB());
    else
        a = new A(new DervedB());
    delete a;
    */
    return 0;
}
/**
 * @brief  在上述这种情况下，A 对象直接依赖于 Base 接口对象，这样一般没问题，但是如果要根据某些条件去创建A 对象的时候，耦合性就产生了。
 * 在上面的例子中， A 对象 和 Base 对象之间的耦合性就产生了，当 Base 对象再新扩展一个派生类时，创建A 对象时，也不得不增加一个分支，
 * 这使得创建某种A 对象变得困难，也违背了“开放——封闭”原则。耦合性产生的原因在于A 对象的创建直接依赖于new 外部对象，这属于硬编码，
 * 使二者紧耦合，失去了灵活性。一种解决办法是通过工厂模式来创建对象
 * 
 */

